package main

import (
	"fmt"
	"net"
	"strings"
)

type User struct {
	Name string
	Addr string
	C    chan string // 每个用户都会有一个Channel
	conn net.Conn    // 每个用户都会维护这一个连接套接字(私有)

	server *Server // 当前用户是属于哪个Server
}

// 创建用户的方法
func NewUser(conn net.Conn, server *Server) *User {
	userAddr := conn.RemoteAddr().String()
	user := &User{
		Name:   userAddr,
		Addr:   userAddr,
		C:      make(chan string),
		conn:   conn,
		server: server,
	}

	// 启动监听当前User Channel消息的goroutine
	go user.ListenMessage()

	return user
}

// 监听当前User Channel的方法，一旦有消息，就直接发送给对端的客户端
func (this *User) ListenMessage() {
	for true {
		msg := <-this.C
		this.conn.Write([]byte(msg + "\n"))
	}
}

// 用户上线接口
func (this *User) Online() {
	// 用户上线，将用户加入到OnlineMap中
	this.server.mapLock.Lock()
	this.server.OnlineMap[this.Name] = this
	this.server.mapLock.Unlock()

	// 广播当前用户上线消息（给其他Online用户）
	this.server.BroadCast(this, "Online!")
}

// 用户下线接口
func (this *User) Offline() {
	// 用户下线，将用户从OnlineMap中删除
	this.server.mapLock.Lock()
	delete(this.server.OnlineMap, this.Name)
	this.server.mapLock.Unlock()

	// 广播当前用户下线消息（给其他Online用户）
	this.server.BroadCast(this, "Offline...")
}

// 用户处理消息的接口
func (this *User) DoMessage(msg string) {
	// 假设，当收到的消息为who时，我们就将当前在线用户的列表返回给他
	fmt.Println("收到消息：", msg)
	if msg == "w" {
		this.server.mapLock.Lock()
		for _, user := range this.server.OnlineMap {
			onlineMsg := "[" + user.Addr + "]" + user.Name + ":Online..."
			this.SendMsg(onlineMsg)
		}
		this.server.mapLock.Unlock()
	} else if len(msg) > 7 && msg[:7] == "rename|" { // 如果消息以rename|开头，则认为是修改用户名
		newName := strings.Split(msg, "|")[1]
		fmt.Println("newName=", newName)
		// 判断name是否存在
		_, ok := this.server.OnlineMap[newName]
		if ok {
			this.SendMsg("already exist!")
		} else {
			this.server.mapLock.Lock()
			delete(this.server.OnlineMap, this.Name)
			this.Name = newName
			this.server.OnlineMap[newName] = this
			this.server.mapLock.Unlock()
			this.SendMsg("succeed!")
		}
	} else if len(msg) > 3 && msg[:3] == "to|" { // 如果消息格式是to|张三|消息内容，则认为是私聊
		// 获取对方用户名
		remoteName := strings.TrimSpace(strings.Split(msg, "|")[1])
		if remoteName == "" {
			this.SendMsg("err format")
			return
		}
		// 根据用户名，获取对象user对象
		remoteUser, ok := this.server.OnlineMap[remoteName]
		if !ok {
			this.SendMsg("remote user not exist")
			return
		}

		// 将消息发送给remoteUser
		content := strings.TrimSpace(strings.Split(msg, "|")[2])
		if content == "" {
			this.SendMsg("err format")
			return
		}
		remoteMsg := this.Name + "say to u:" + content
		remoteUser.C <- remoteMsg
	} else {
		this.server.BroadCast(this, msg)
	}
}

// 通过conn给当前用户发送消息
func (this *User) SendMsg(msg string) {
	fmt.Println("返回消息：", msg)
	this.conn.Write([]byte(msg + "\n"))
}
